#include <stdio.h>

/*
 *线性同余法与伪随机函数
 */

/* constants from the Numberical Recipes book */
#define RNG_A 1664525
#define RNG_B 1013904223

static unsigned int rand_state;

void my_srand(unsigned int init)
{
	rand_state = init;
}

int my_rand()
{
	rand_state = rand_state * RNG_A;
	rand_state = rand_state + RNG_B;

	return rand_state & 0x7fff;
}

int main()
{
	printf("%d\n", my_rand());

	return 0;
}

#if 0

"线性同余法"大概是生成随机数的最简方法。它原理简单(只涉及乘法、加法和与运算)。

my_rand的返回值应当介于0~32767之间。如果有意生成32位的伪随机数，那么就不必在此处进行与运算。

#endif

#if 0
/*
 * intel
 */
0000000000001149 <my_srand>:
    1149:	f3 0f 1e fa          	endbr64 
    114d:	55                   	push   %rbp
    114e:	48 89 e5             	mov    %rsp,%rbp
    1151:	89 7d fc             	mov    %edi,-0x4(%rbp)
    1154:	8b 45 fc             	mov    -0x4(%rbp),%eax
    1157:	89 05 b7 2e 00 00    	mov    %eax,0x2eb7(%rip)        # 4014 <rand_state>
    115d:	90                   	nop
    115e:	5d                   	pop    %rbp
    115f:	c3                   	retq   

0000000000001160 <my_rand>:
    1160:	f3 0f 1e fa          	endbr64 
    1164:	55                   	push   %rbp
    1165:	48 89 e5             	mov    %rsp,%rbp
    1168:	8b 05 a6 2e 00 00    	mov    0x2ea6(%rip),%eax        # 4014 <rand_state>
    116e:	69 c0 0d 66 19 00    	imul   $0x19660d,%eax,%eax
    1174:	89 05 9a 2e 00 00    	mov    %eax,0x2e9a(%rip)        # 4014 <rand_state>
    117a:	8b 05 94 2e 00 00    	mov    0x2e94(%rip),%eax        # 4014 <rand_state>
    1180:	05 5f f3 6e 3c       	add    $0x3c6ef35f,%eax
    1185:	89 05 89 2e 00 00    	mov    %eax,0x2e89(%rip)        # 4014 <rand_state>
    118b:	8b 05 83 2e 00 00    	mov    0x2e83(%rip),%eax        # 4014 <rand_state>
    1191:	25 ff 7f 00 00       	and    $0x7fff,%eax
    1196:	5d                   	pop    %rbp
    1197:	c3                   	retq   

0000000000001198 <main>:
    1198:	f3 0f 1e fa          	endbr64 
    119c:	55                   	push   %rbp
    119d:	48 89 e5             	mov    %rsp,%rbp
    11a0:	b8 00 00 00 00       	mov    $0x0,%eax
    11a5:	e8 b6 ff ff ff       	callq  1160 <my_rand>
    11aa:	89 c6                	mov    %eax,%esi
    11ac:	48 8d 3d 51 0e 00 00 	lea    0xe51(%rip),%rdi        # 2004 <_IO_stdin_used+0x4>
    11b3:	b8 00 00 00 00       	mov    $0x0,%eax
    11b8:	e8 93 fe ff ff       	callq  1050 <printf@plt>
    11bd:	b8 00 00 00 00       	mov    $0x0,%eax
    11c2:	5d                   	pop    %rbp
    11c3:	c3                   	retq   
    11c4:	66 2e 0f 1f 84 00 00 	nopw   %cs:0x0(%rax,%rax,1)
    11cb:	00 00 00 
    11ce:	66 90                	xchg   %ax,%ax

/*
 * arm
 */
000000000040055c <my_srand>:
  40055c:	d10043ff 	sub	sp, sp, #0x10
  400560:	b9000fe0 	str	w0, [sp, #12]
  400564:	b0000080 	adrp	x0, 411000 <__libc_start_main@GLIBC_2.17>
  400568:	9100d000 	add	x0, x0, #0x34
  40056c:	b9400fe1 	ldr	w1, [sp, #12]
  400570:	b9000001 	str	w1, [x0]
  400574:	d503201f 	nop
  400578:	910043ff 	add	sp, sp, #0x10
  40057c:	d65f03c0 	ret

0000000000400580 <my_rand>:
  400580:	b0000080 	adrp	x0, 411000 <__libc_start_main@GLIBC_2.17>
  400584:	9100d000 	add	x0, x0, #0x34
  400588:	b9400001 	ldr	w1, [x0]
  40058c:	528cc1a0 	mov	w0, #0x660d                	// #26125
  400590:	72a00320 	movk	w0, #0x19, lsl #16
  400594:	1b007c21 	mul	w1, w1, w0
  400598:	b0000080 	adrp	x0, 411000 <__libc_start_main@GLIBC_2.17>
  40059c:	9100d000 	add	x0, x0, #0x34
  4005a0:	b9000001 	str	w1, [x0]
  4005a4:	b0000080 	adrp	x0, 411000 <__libc_start_main@GLIBC_2.17>
  4005a8:	9100d000 	add	x0, x0, #0x34
  4005ac:	b9400001 	ldr	w1, [x0]
  4005b0:	529e6be0 	mov	w0, #0xf35f                	// #62303
  4005b4:	72a78dc0 	movk	w0, #0x3c6e, lsl #16
  4005b8:	0b000021 	add	w1, w1, w0
  4005bc:	b0000080 	adrp	x0, 411000 <__libc_start_main@GLIBC_2.17>
  4005c0:	9100d000 	add	x0, x0, #0x34
  4005c4:	b9000001 	str	w1, [x0]
  4005c8:	b0000080 	adrp	x0, 411000 <__libc_start_main@GLIBC_2.17>
  4005cc:	9100d000 	add	x0, x0, #0x34
  4005d0:	b9400000 	ldr	w0, [x0]
  4005d4:	12003800 	and	w0, w0, #0x7fff
  4005d8:	d65f03c0 	ret

00000000004005dc <main>:
  4005dc:	a9bf7bfd 	stp	x29, x30, [sp, #-16]!
  4005e0:	910003fd 	mov	x29, sp
  4005e4:	97ffffe7 	bl	400580 <my_rand>
  4005e8:	2a0003e1 	mov	w1, w0
  4005ec:	90000000 	adrp	x0, 400000 <_init-0x3e8>
  4005f0:	911ae000 	add	x0, x0, #0x6b8
  4005f4:	97ffff97 	bl	400450 <printf@plt>
  4005f8:	52800000 	mov	w0, #0x0                   	// #0
  4005fc:	a8c17bfd 	ldp	x29, x30, [sp], #16
  400600:	d65f03c0 	ret
  400604:	00000000 	.inst	0x00000000 ; undefined


#endif

